#!/usr/bin/env python3.9
# Chris Baird <cjb@brushtail.apana.org.au> did this January 2022

import sys, colorsys
from PIL import Image

margin = 6
noisemargin = 96 # magic varible - needs calculation
morsetable = \
 ( 128, 174,  74, 128,  19, 128,  68, 122, 180, 182, 128,  84,
   206, 134,  86, 148, 252, 124,  60,  28,  12,   4, 132, 196,
   228, 244, 226, 170, 128, 140, 128,  50, 106,  96, 136, 168,
   144,  64,  40, 208,   8,  32, 120, 176,  72, 224, 160, 240,
   104, 216,  80,  16, 192,  48,  24, 112, 104, 184, 200)

def bin2morse (a):
    for i in range(59):
        if morsetable[i] == a: return chr(32+i)
    return " "

im = Image.open(sys.argv[1]).convert('YCbCr')
b=""
for y in range(margin, im.size[1]-margin):
    for x in range(margin, im.size[0]-margin):
        i = im.getpixel((x,y))[0]
        if i < noisemargin: i2 = '1'
        else: i2 = '0';
        b += i2

# Discover the ditsize by finding the most frequent signal lengths.
# 'dit' is usually the most common, 'dah' is second.
l=b.split('0')
l.sort()
g={}
for i in l:
    try: g[i] += 1
    except: g[i] = 0
del g['']
l = sorted(g, key=g.__getitem__,reverse=True)
(ditsize, dahsize) = (len(l[0]), len(l[1]))

if ditsize > dahsize: (ditsize, dahsize) = (dahsize, ditsize)
if ditsize*3 == dahsize: s = "..with high confidence"
else: s = "..with low confidence, ditsize="+str(ditsize)+" dahsize="+str(dahsize)
print ("ditsize =", ditsize, s)

import re # remove the extra long runs of 0's
b = re.sub("000000"*ditsize + "+","0000000", b.strip('0'))

# process! .. The "2*ditsize" needs to be properly calculated
w = re.split('(0+)', b)
code = 0
bi = 128
s = ""
ss = ""
for c in w:
    l = len(c)
    if c[0] == '1':
        if l > 2*ditsize:
            code |= bi
            ss += "-"
        else: ss += "."
        bi >>= 1
    else:
        if l < 2*ditsize: continue  # intra-symbol dit

        if l >= 2*ditsize:
            code |= bi
            s += bin2morse(code)
            ss = ""
            code = 0
            bi = 128
        if l >= 3.5*ditsize: s+= " "

print (s)
